
package com.sping.registry;

import com.sping.loadbalance.RandomLoadBalance;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.ArrayList;
import java.util.List;


/**
 * @描述:
 * @作者:Marks
 * @日期:19:31 2018-10-14
 * @版权:
 */

public class ServiceDiscoverImpl implements IServiceDiscovery {

    private CuratorFramework curatorFramework;

    private List<String> repos = new ArrayList<>();

   public ServiceDiscoverImpl() {
        curatorFramework = CuratorFrameworkFactory.builder().connectString(ZkConfig.CONNECTION_STR).sessionTimeoutMs(4000)
                .retryPolicy(new ExponentialBackoffRetry(1000, 10))
                .build();
        curatorFramework.start();
    }

    @Override
    public String discovery(String serviceName) {

        String path = ZkConfig.ZK_REGSITER_PATH + "/" + serviceName;
        try {
            repos = curatorFramework.getChildren().forPath(path);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //动态感知服务节点的一个变化 zk监听机制
        registerWatch(path);


        //负载均衡
        RandomLoadBalance loadBalance = new RandomLoadBalance();
        return loadBalance.select(repos);
    }

    private void registerWatch(final String path) {
        PathChildrenCache childrenCache=new PathChildrenCache(curatorFramework,path,true);
        PathChildrenCacheListener pathChildrenCacheListener=(curatorFramework, pathChildrenCacheEvent) ->{
            repos=curatorFramework.getChildren().forPath(path);
        } ;
        childrenCache.getListenable().addListener(pathChildrenCacheListener);

        try {
            childrenCache.start();
        } catch (Exception e) {
            throw new RuntimeException("注册PathChild Watcher 异常"+e);
        }
    }
}

